From 50a5deb8e382a4c116aa383e9c932d42a19efbfb Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Mon, 31 Oct 2016 16:26:50 +0000 Subject: [PATCH] gsk: Add internal Renderer.create_cairo_surface() We need an overridable entry point for GskRenderer to create Cairo surfaces. Implementations of GskRenderer can override create_cairo_surface() to create efficient surfaces, possibly with zero copies involved, depending on the GDK backend. --- gsk/gskrenderer.c | 31 +++++++++++++++++++++++++++++++ gsk/gskrendererprivate.h | 17 +++++++++++++---- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index 2d7cdec4d1..21236cfc13 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -115,6 +115,24 @@ gsk_renderer_real_render (GskRenderer *self, GSK_RENDERER_WARN_NOT_IMPLEMENTED_METHOD (self, render); } +static cairo_surface_t * +gsk_renderer_real_create_cairo_surface (GskRenderer *self, + cairo_format_t format, + int width, + int height) +{ + GskRendererPrivate *priv = gsk_renderer_get_instance_private (self); + int scale_factor = priv->scale_factor > 0 ? priv->scale_factor : 1; + int real_width = width * scale_factor; + int real_height = height * scale_factor; + + cairo_surface_t *res = cairo_image_surface_create (format, real_width, real_height); + + cairo_surface_set_device_scale (res, scale_factor, scale_factor); + + return res; +} + static void gsk_renderer_dispose (GObject *gobject) { @@ -220,6 +238,7 @@ gsk_renderer_class_init (GskRendererClass *klass) klass->realize = gsk_renderer_real_realize; klass->unrealize = gsk_renderer_real_unrealize; klass->render = gsk_renderer_real_render; + klass->create_cairo_surface = gsk_renderer_real_create_cairo_surface; gobject_class->constructed = gsk_renderer_constructed; gobject_class->set_property = gsk_renderer_set_property; @@ -733,6 +752,18 @@ gsk_renderer_get_for_display (GdkDisplay *display) return g_object_new (renderer_type, "display", display, NULL); } +cairo_surface_t * +gsk_renderer_create_cairo_surface (GskRenderer *renderer, + cairo_format_t format, + int width, + int height) +{ + g_return_val_if_fail (GSK_IS_RENDERER (renderer), NULL); + g_return_val_if_fail (width > 0 && height > 0, NULL); + + return GSK_RENDERER_GET_CLASS (renderer)->create_cairo_surface (renderer, format, width, height); +} + static void gsk_renderer_set_cairo_context (GskRenderer *renderer, cairo_t *cr) diff --git a/gsk/gskrendererprivate.h b/gsk/gskrendererprivate.h index d702ae5a78..57f7e861f3 100644 --- a/gsk/gskrendererprivate.h +++ b/gsk/gskrendererprivate.h @@ -42,15 +42,24 @@ struct _GskRendererClass void (* render) (GskRenderer *renderer, GskRenderNode *root); + + cairo_surface_t * (* create_cairo_surface) (GskRenderer *renderer, + cairo_format_t, + int width, + int height); }; gboolean gsk_renderer_is_realized (GskRenderer *renderer); -GskRenderNode * gsk_renderer_get_root_node (GskRenderer *renderer); -GdkDrawingContext * gsk_renderer_get_drawing_context (GskRenderer *renderer); -cairo_t * gsk_renderer_get_cairo_context (GskRenderer *renderer); +GskRenderNode * gsk_renderer_get_root_node (GskRenderer *renderer); +GdkDrawingContext * gsk_renderer_get_drawing_context (GskRenderer *renderer); +cairo_t * gsk_renderer_get_cairo_context (GskRenderer *renderer); +cairo_surface_t * gsk_renderer_create_cairo_surface (GskRenderer *renderer, + cairo_format_t format, + int width, + int height); -GskProfiler * gsk_renderer_get_profiler (GskRenderer *renderer); +GskProfiler * gsk_renderer_get_profiler (GskRenderer *renderer); G_END_DECLS -- 2.30.2